package com.spi.soconversion.util;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;

import com.spi.soconversion.base.SOCException;

public class BatchProcessor {
	
	private static final String TOTAL_RECORDS_PROCESSED = "TOTAL_RECORDS_PROCESSED";
	private static final String BATCH_NUMBER = "BATCH_NUMBER";
	private String d_logFileName = null;
	private SOCFileWriter d_FileWriter = null;
	
	public BatchProcessor(String logFileName, SOCFileWriter fileWriter)
	{
		d_logFileName = logFileName;
		d_FileWriter = fileWriter;
	}
	
	/**
     * This Method gets the batch number. 
     * @throws SOCException - wraps all the exceptions that occur while processing
     */
    public int getBatchNumber(String converionType) throws SOCException
    {
    	int result = 0;
    	String batchInfoQuery = QueryReader.getQuery(QueryConstants.SELECT_BATCH_NUMBER_QUERY);
    	PreparedStatement batchStmt=null;
    	ResultSet rsBatchInfo=null;
    	d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.MESSAGE_RETRIEVE_BATCH_NUMBER_STARTS));
    	try
		{
    		batchStmt=DBConnection.getConnection().prepareStatement(batchInfoQuery);
    		batchStmt.setString(1, converionType);
    		rsBatchInfo=batchStmt.executeQuery();
			if(rsBatchInfo!=null)
			{
				rsBatchInfo.next();
				result = rsBatchInfo.getInt(BATCH_NUMBER);
				
			}			
		}
		catch(SQLException sqle)
		{
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
    				ErrorConstants.FAILED_FETCH_BATCH_NUMBER)+converionType+SOCConstants.NEW_LINE+sqle.getMessage()));
			throw new SOCException(
            		ErrorMessageReader.getError(
            				ErrorConstants.FAILED_FETCH_BATCH_NUMBER)+converionType ,sqle);
    		
		}	
		d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.MESSAGE_RETRIEVE_BATCH_NUMBER_ENDS));
		return result;
    }
    
    /**
     * This Method gets the total records processed. 
     * @throws SOCException - wraps all the exceptions that occur while processing
     */
    public int getTotalRecordsProcessed(int batchNum,String converionType) throws SOCException
    {
    	int result = 0;
    	String batchInfoQuery = QueryReader.getQuery(QueryConstants.SELECT_TOTAL_RECORDS_PROCESSED_QUERY);
    	PreparedStatement batchStmt=null;
    	ResultSet rsBatchInfo=null;
    	d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.MESSAGE_RETRIEVE_TOTAL_RECORDS_PROCESSED_STARTS));
    	try
		{
    		batchStmt=DBConnection.getConnection().prepareStatement(batchInfoQuery);
    		batchStmt.setString(1, converionType);
    		batchStmt.setInt(2, batchNum);
    		rsBatchInfo=batchStmt.executeQuery();
			if(rsBatchInfo!=null)
			{
				rsBatchInfo.next();
				result= rsBatchInfo.getInt(TOTAL_RECORDS_PROCESSED);
				
			}			
		}
		catch(SQLException sqle)
		{
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
    				ErrorConstants.FAILED_FETCH_BATCH_INFO_FOR_TOTAL_RECORDS)+converionType+SOCConstants.BLANK_STRING+batchNum+SOCConstants.NEW_LINE+sqle.getMessage()));
			throw new SOCException(
            		ErrorMessageReader.getError(
            				ErrorConstants.FAILED_FETCH_BATCH_INFO_FOR_TOTAL_RECORDS) + converionType+SOCConstants.BLANK_STRING+batchNum,sqle);
    		
		}	
		d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(SOCConstants.MESSAGE_RETRIEVE_TOTAL_RECORDS_PROCESSED_ENDS));
		return result;
    }
    
    /**
     * This Method updates the batch information for the current batch. 
     * @throws SOCException - wraps all the exceptions that occur while processing
     */
    public void updateBatchInfo(int batchNum, int totalRecProcessed,int recordsFetched, int recordsDataIssues,long recordsFailedValidation,String converionType,Timestamp startTime,Timestamp endTime) throws SOCException
    {
    	String batchUpdateQuery = QueryReader.getQuery(QueryConstants.INSERT_CONVERSION_BATCH_RECORDS_QUERY);
    	PreparedStatement batchStmt=null;
    	int recordCount=0;
    	try
		{
    		batchStmt=DBConnection.getConnection().prepareStatement(batchUpdateQuery);
    		batchStmt.setString(1, converionType);
    		batchStmt.setInt(2, batchNum);
    		batchStmt.setInt(3, recordsFetched);    		
    		batchStmt.setInt(4, totalRecProcessed);
    		batchStmt.setInt(5, recordsDataIssues);
    		batchStmt.setLong(6, recordsFailedValidation);
    		batchStmt.setTimestamp(7,startTime);
    		batchStmt.setTimestamp(8, endTime);
    		
    		recordCount=batchStmt.executeUpdate();
    		if(recordCount==0)
			{
				d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
	            				ErrorConstants.NO_RECORD_POPULATION_CONVERSION_BATCH_RECORDS)));
				throw new SOCException(
	            		ErrorMessageReader.getError(
	            				ErrorConstants.NO_RECORD_POPULATION_CONVERSION_BATCH_RECORDS));
			}	
		}
		catch(SQLException sqle)
		{
			d_FileWriter.write(d_logFileName, SOCUtility.writeLogMessage(ErrorMessageReader.getError(
    				ErrorConstants.FAILED_UPDATE_BATCH_INFO)+SOCConstants.NEW_LINE+sqle.getMessage()));
			throw new SOCException(
            		ErrorMessageReader.getError(
            				ErrorConstants.FAILED_UPDATE_BATCH_INFO) ,sqle);
    		
		}	
    }

}
